package com.luhuiguo.cms.client.presenter;

import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.luhuiguo.cms.client.GlobalConstants;
import com.luhuiguo.cms.client.GlobalMessages;
import com.luhuiguo.cms.shared.event.AddArticleEvent;
import com.luhuiguo.cms.shared.event.AddArticleEventHandler;
import com.luhuiguo.cms.shared.event.AddChannelEvent;
import com.luhuiguo.cms.shared.event.AddChannelEventHandler;
import com.luhuiguo.cms.shared.event.ArticleCreatedEvent;
import com.luhuiguo.cms.shared.event.ArticleCreatedEventHandler;
import com.luhuiguo.cms.shared.event.ArticleUpdatedEvent;
import com.luhuiguo.cms.shared.event.ArticleUpdatedEventHandler;
import com.luhuiguo.cms.shared.event.EditArticleCancelledEvent;
import com.luhuiguo.cms.shared.event.EditArticleCancelledEventHandler;
import com.luhuiguo.cms.shared.event.EditArticleEvent;
import com.luhuiguo.cms.shared.event.EditArticleEventHandler;
import com.luhuiguo.cms.shared.event.EditChannelCancelledEvent;
import com.luhuiguo.cms.shared.event.EditChannelCancelledEventHandler;
import com.luhuiguo.cms.shared.event.EditChannelEvent;
import com.luhuiguo.cms.shared.event.EditChannelEventHandler;
import com.luhuiguo.cms.shared.event.LoadArticlesEvent;
import com.luhuiguo.cms.shared.event.LoadArticlesEventHandler;
import com.luhuiguo.cms.shared.model.ChannelModel;
import com.luhuiguo.cms.shared.model.ChannelTreeModel;
import com.luhuiguo.cms.shared.rpc.CreateDraftArticle;
import com.luhuiguo.cms.shared.rpc.CreateDraftArticleResult;
import com.luhuiguo.cms.shared.rpc.GetArticle;
import com.luhuiguo.cms.shared.rpc.GetArticleResult;
import com.luhuiguo.cms.shared.rpc.GetChannel;
import com.luhuiguo.cms.shared.rpc.GetChannelResult;
import com.luhuiguo.gwt.dispatcher.client.DispatcherAsync;
import com.luhuiguo.gwt.presenter.client.EventBus;
import com.luhuiguo.gwt.presenter.client.widget.WidgetContainerDisplay;
import com.luhuiguo.gwt.presenter.client.widget.WidgetContainerPresenter;

public class MainPresenter extends WidgetContainerPresenter<MainPresenter.Display> {

    public interface Display extends WidgetContainerDisplay {

    }

    @SuppressWarnings("unused")
    private GlobalConstants constants;

    private GlobalMessages messages;

    private DispatcherAsync dispatcher;

    private EditChannelPresenter editChannelPresenter;

    private ArticlesPresenter articlesPresenter;

    private EditArticlePresenter editArticlePresenter;

    private ChannelTreeModel channelTreeModel;

    @Inject
    public MainPresenter(Display display, EventBus eventBus, DispatcherAsync dispatcher, GlobalConstants constants,
            GlobalMessages messages, EditChannelPresenter editChannelPresenter, ArticlesPresenter articlesPresenter,
            EditArticlePresenter editArticlePresenter) {
        super(display, eventBus, editChannelPresenter, articlesPresenter, editArticlePresenter);
        this.dispatcher = dispatcher;
        this.constants = constants;
        this.messages = messages;

        this.editChannelPresenter = editChannelPresenter;
        this.articlesPresenter = articlesPresenter;
        this.editArticlePresenter = editArticlePresenter;
    }

    @Override
    protected void onBind() {
        super.onBind();

        registerHandler(eventBus.addHandler(LoadArticlesEvent.TYPE, new LoadArticlesEventHandler() {

            @Override
            public void onLoadArticles(LoadArticlesEvent event) {
                channelTreeModel = event.getChannelTreeModel();
                showArticleList(channelTreeModel);
            }

        }));

        registerHandler(eventBus.addHandler(EditChannelCancelledEvent.TYPE, new EditChannelCancelledEventHandler() {

            @Override
            public void onEditChannelCancelled(EditChannelCancelledEvent event) {
                channelTreeModel = event.getChannelTreeModel();
                showArticleList(channelTreeModel);
            }

        }));

        registerHandler(eventBus.addHandler(AddChannelEvent.TYPE, new AddChannelEventHandler() {
            @Override
            public void onAddChannel(AddChannelEvent event) {
                showAddChannel(event.getChannelTreeModel());

            }

        }));

        registerHandler(eventBus.addHandler(EditChannelEvent.TYPE, new EditChannelEventHandler() {
            @Override
            public void onEditChannel(EditChannelEvent event) {
                showEditChannel(event.getChannelTreeModel());
            }

        }));

        registerHandler(eventBus.addHandler(AddArticleEvent.TYPE, new AddArticleEventHandler() {

            @Override
            public void onAddArticle(AddArticleEvent event) {
                showAddArticle(event.getChannelId());

            }

        }));

        registerHandler(eventBus.addHandler(EditArticleEvent.TYPE, new EditArticleEventHandler() {

            @Override
            public void onEditArticle(EditArticleEvent event) {
                showEditArticle(event.getArticleId());

            }

        }));

        registerHandler(eventBus.addHandler(EditArticleCancelledEvent.TYPE, new EditArticleCancelledEventHandler() {

            @Override
            public void onEditArticleCancelled(EditArticleCancelledEvent event) {
                showArticleList(channelTreeModel);
            }

        }));

        registerHandler(eventBus.addHandler(ArticleCreatedEvent.TYPE, new ArticleCreatedEventHandler() {
            @Override
            public void onArticleCreated(ArticleCreatedEvent event) {
                showArticleList(channelTreeModel);
                Info.display(messages.success(), messages.articleCreated(event.getArticle().getTitle()));

            }
        }));

        registerHandler(eventBus.addHandler(ArticleUpdatedEvent.TYPE, new ArticleUpdatedEventHandler() {
            @Override
            public void onArticleUpdated(ArticleUpdatedEvent event) {
                showArticleList(channelTreeModel);
                Info.display(messages.success(), messages.articleUpdated(event.getArticle().getTitle()));

            }
        }));

    }

    protected void showEditArticle(final Long articleId) {
        dispatcher.execute(new GetArticle(articleId), new AsyncCallback<GetArticleResult>() {
            @Override
            public void onFailure(Throwable caught) {
                GWT.log(messages.loadArticleFailed(articleId), caught);
                MessageBox.alert(messages.error(), messages.loadArticleFailed(articleId), null);
            }

            @Override
            public void onSuccess(GetArticleResult result) {
                editArticlePresenter.revealDisplay(result.get());
            }
        });

    }

    protected void showAddArticle(Long channelId) {

        dispatcher.execute(new CreateDraftArticle(channelId), new AsyncCallback<CreateDraftArticleResult>() {
            @Override
            public void onFailure(Throwable caught) {
                MessageBox.alert(messages.error(), messages.saveArticleFailed(""), null);
            }

            @Override
            public void onSuccess(CreateDraftArticleResult result) {
                editArticlePresenter.revealDisplay(result.get());
            }
        });

    }

    protected void showArticleList(ChannelTreeModel channelTreeModel) {
        articlesPresenter.revealDisplay(channelTreeModel);
    }

    protected void showEditChannel(final ChannelTreeModel channelTreeModel) {

        dispatcher.execute(new GetChannel(channelTreeModel.getId()), new AsyncCallback<GetChannelResult>() {
            @Override
            public void onFailure(Throwable caught) {
                GWT.log(messages.loadChannelFailed(channelTreeModel.getId()), caught);
                MessageBox.alert(messages.error(), messages.loadChannelFailed(channelTreeModel.getId()), null);
            }

            @Override
            public void onSuccess(GetChannelResult result) {
                editChannelPresenter.revealDisplay(channelTreeModel, result.get());
            }
        });

    }

    protected void showAddChannel(ChannelTreeModel channelTreeModel) {
        ChannelModel channelModel = new ChannelModel();

        channelModel.setParentId(channelTreeModel == null ? null : channelTreeModel.getId());
        editChannelPresenter.revealDisplay(channelTreeModel, channelModel);
    }

}
